import Axios, { AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse } from 'axios'

import { useUserStore } from '@/store/modules/user'
import { localGet } from '@/utils/common'
import { message } from 'ant-design-vue'

const baseURL: string = import.meta.env.VITE_API_BASE_URL || ''
const axios = Axios.create({
    // baseURL, // 基础 url

    withCredentials: true,
    timeout: 600000, // 超时 10s
    headers: {
        'X-Requested-With': 'XMLHttpRequest'
    }
})

axios.interceptors.request.use(
    (config: AxiosRequestConfig) => {
        const baseURL: string = import.meta.env.VITE_API_BASE_URL || ''
        const str = 'http://127.0.0.1:8081'
        if (config.url?.includes(str)) {
            config.url = config.url.replace(str, baseURL)
        }
        const str1 = 'http://10.20.0.226:8081'
        if (config.url?.includes(str1)) {
            config.url = config.url.replace(str1, baseURL)
        }
        const str2 = 'http://10.90.0.72:8081'
        if (config.url?.includes(str2)) {
            config.url = config.url.replace(str2, baseURL)
        }
        // 附加上token和uid
        const APP_ID = localGet('al__APPID')
        if (!config.headers) {
            config.headers = {} as AxiosRequestHeaders
        }
        const current_user_id = 100650
        const current_tenant_id = 2
        const current_tenant_name = '冯腾飞'
        const uid = '0618f1b9-bbfb-442e-8582-368a656ef9da'
        const ppmToken =
            'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyVXVpZCI6IjA2MThmMWI5LWJiZmItNDQyZS04NTgyLTM2OGE2NTZlZjlkYSIsImV4cCI6MTcwNzEwMTY1OCwidXNlcklkIjoiMTAwNjUwIiwidGltZXN0YW1wIjoiMTcwMTkxNzY1ODAzMyJ9.g5pqyVCTEu-MvdvMF9jVU7FQU1tdRikK0jyNAvSu2hI'
        const appId = 'product-container'
        const currentUserName = '5Yav6IW+6aOe'
        if (current_user_id) {
            config.headers['current_user_id'] = current_user_id
        }
        if (current_tenant_id) {
            config.headers['current_tenant_id'] = current_tenant_id
        }
        if (uid) {
            config.headers['uid'] = uid
        }
        if (ppmToken) {
            config.headers['token'] = ppmToken
        }
        if (appId) {
            config.headers['appId'] = appId
        }
        if (currentUserName) {
            config.headers['current_user_name'] = currentUserName
        }
        return config
    },
    (error: any) => {
        return Promise.reject(error)
    }
)

axios.interceptors.response.use(
    response => {
        // 服务器正常返回
        const data = response.data
        if (response?.config?.responseType) {
            if (['arraybuffer', 'blob'].includes(response.config.responseType)) {
                return response
            }
        }
        // 判断http状态码为2xx
        if (response.status >= 200 && response.status < 300) {
            return response
        } else {
            // 其他错误，直接抛出错误
            return Promise.reject(data.errorCode)
        }
    },
    error => {
        return Promise.reject({
            code: error.response.status,
            message: error.response.statusText
        })
    }
)

export default axios

export function get<T = any, D = any>(
    url: string,
    params?: D,
    config?: AxiosRequestConfig<D>
): Promise<HttpResponse<T>> {
    const localConfig = config ? config : ({} as AxiosRequestConfig<D>)
    if (params) {
        localConfig.params = Object.assign({}, localConfig.params ? localConfig.params : {}, params)
    }
    return axios.get<HttpResponse<T>>(url, localConfig).then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
}

export function getWithErrorMessage<T = any, D = any>(
    url: string,
    params?: D,
    config?: AxiosRequestConfig<D>
): Promise<HttpResponse<T>> {
    const localConfig = config ? config : ({} as AxiosRequestConfig<D>)
    if (params) {
        localConfig.params = Object.assign({}, localConfig.params ? localConfig.params : {}, params)
    }
    return axios
        .get<HttpResponse<T>>(url, localConfig)
        .then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
        .then(resp => {
            if (resp.status !== 'success') {
                message.error(resp.errorMsg)
                return Promise.reject(resp.errorMsg)
            }
            return resp
        })
}

export function post<T = any, D = any>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig<D>
): Promise<HttpResponse<T>> {
    return axios.post<HttpResponse<T>>(url, data, config).then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
}

export function postWithErrorMessage<T = any, D = any>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig<D>
): Promise<HttpResponse<T>> {
    return axios
        .post<HttpResponse<T>>(url, data, config)
        .then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
        .then(resp => {
            if (resp.status !== 'success') {
                message.error(resp.errorMsg)
                return Promise.reject(resp.errorMsg)
            }
            return resp
        })
}

export function put<T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<HttpResponse<T>> {
    return axios.put<HttpResponse<T>>(url, data, config).then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
}
export function putWithErrorMessage<T = any, D = any>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig<D>
): Promise<HttpResponse<T>> {
    return axios
        .put<HttpResponse<T>>(url, data, config)
        .then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
        .then(resp => {
            if (resp.status !== 'success') {
                message.error(resp.errorMsg)
                return Promise.reject(resp.errorMsg)
            }
            return resp
        })
}

export function patch<T = any, D = any>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig<D>
): Promise<HttpResponse<T>> {
    return axios.patch<HttpResponse<T>>(url, data, config).then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
}

export function del<T = any, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<HttpResponse<T>> {
    return axios.delete<HttpResponse<T>>(url, config).then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
}

// TODO add upload and download

export function request<T = any, D = any>(config: AxiosRequestConfig<D>): Promise<HttpResponse<T>> {
    return axios.request<HttpResponse<T>>(config).then((resp: AxiosResponse<HttpResponse<T>>) => resp.data)
}

export function requestWithHeaders<T = any, D = any>(config: AxiosRequestConfig<D>): Promise<HttpResponse<T>> {
    return axios.request<HttpResponse<T>>(config).then((resp: AxiosResponse<HttpResponse<T>>) => resp)
}
